﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;

namespace CYTS.Aoyou.Framework.Utility
{
    /// <summary>
    /// HTTP请求类
    /// </summary>
    public class WebRequestHelper
    {
        //默认请求编码
        private static readonly Encoding _defaultRequestEncoding = Encoding.UTF8;
        //默认响应编码
        private static readonly Encoding _defaultResponseEncoding = Encoding.UTF8;
        //默认超时时间,单位(毫秒)
        private static readonly int _defaultTimeout = 100000;

        public static string Get(string url)
        {
            string result = Get(url, _defaultTimeout);

            return result;
        }

        public static string Get(string url, int timeout)
        {
            string result = Get(url, timeout, _defaultResponseEncoding, null, null);

            return result;
        }

        public static string Get(string url, Encoding responseEncoding)
        {
            string result = Get(url, _defaultTimeout, responseEncoding, null, null);

            return result;
        }

        public static string Get(string url, int timeout, Encoding responseEncoding
            , WebHeaderCollection headers, CookieContainer cookies)
        {
            string result = Request(url, "GET", String.Empty, timeout, responseEncoding, headers, cookies);

            return result;
        }

        public static string Post(string url, string data)
        {
            string result = Post(url, data, _defaultTimeout);

            return result;
        }

        public static string Post(string url, string data, int timeout)
        {
            string result = Post(url, data, timeout, _defaultResponseEncoding, null, null);

            return result;
        }

        public static string Post(string url, string data, Encoding responseEncoding)
        {
            string result = Post(url, data, _defaultTimeout, responseEncoding, null, null);

            return result;
        }

        public static string Post(string url, string data, int timeout, Encoding responseEncoding
            , WebHeaderCollection headers, CookieContainer cookies)
        {
            string result = Request(url, "POST", data, timeout, responseEncoding, headers, cookies);

            return result;
        }

        public static string Request(string url, string method, string data, int timeout, Encoding responseEncoding
            , WebHeaderCollection headers, CookieContainer cookies)
        {
            string result = null;

            HttpWebRequest request = null;

            try
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            catch (Exception ex)
            {
                return null;
            }

            if (request != null)
            {
                if (headers != null)
                {
                    string key = String.Empty;

                    for (int i = 0; i < headers.Keys.Count; i++)
                    {
                        key = headers.Keys[i];

                        request.Headers[key] = headers[key];
                    }
                }

                if (cookies != null)
                {
                    request.CookieContainer = cookies;
                }

                if (timeout <= 0 && timeout != Timeout.Infinite)
                {
                    timeout = _defaultTimeout;
                }

                request.Timeout = timeout;

                if (method.ToUpper() == "POST")
                {
                    byte[] buffer = _defaultRequestEncoding.GetBytes(data);

                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = buffer.Length;

                    Stream requestStream = null;
                    try
                    {
                        requestStream = request.GetRequestStream();
                        requestStream.Write(buffer, 0, buffer.Length);
                    }
                    catch (Exception ex)
                    {
                        return null;
                    }
                    finally
                    {
                        if (requestStream != null)
                            requestStream.Close();
                    }
                }
                else
                {
                    request.Method = "GET";
                    request.ContentType = "text/html";
                }

                result = Request(request, responseEncoding);
            }

            return result;
        }

        public static string Request(HttpWebRequest request, Encoding responseEncoding)
        {
            string result = null;

            Stream stream = null;
            StreamReader streamReader = null;

            try
            {
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;

                if (response != null)
                {
                    stream = response.GetResponseStream();

                    string contentEncoding = response.ContentEncoding.ToLower();

                    //获取流的读取器对象
                    //不同的后备存储器会有多种流（因为有多种编码方式）
                    if (contentEncoding.Contains("gzip"))
                    {
                        streamReader = new StreamReader(new GZipStream(stream, CompressionMode.Decompress));
                    }
                    else if (contentEncoding.Contains("deflate"))
                    {
                        streamReader = new StreamReader(new DeflateStream(stream, CompressionMode.Decompress));
                    }
                    else
                    {
                        streamReader = new StreamReader(stream, responseEncoding);
                    }

                    result = streamReader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                if (streamReader != null)
                    streamReader.Close();

                if (stream != null)
                    stream.Close();
            }

            return result;
        }
    }
}
